/**
 * @file TcpClientImpl.h
 * @author yangx (yangxing2297@163.com)
 * @brief tcp客户端实现类
 * @version 0.1
 * @date 2023-04-07
 * 
 * @copyright Copyright (c) 2023
 * 
 */
#ifndef _TCP_CLIENT_IMPL_H_
#define _TCP_CLIENT_IMPL_H_
#include "TcpClient.h"
#ifdef __linux__
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<errno.h>
#include<unistd.h>
#elif _WIN32
// TODO: adapt to windows system
#endif // 

#include<event.h>
#include<event2/bufferevent.h>
#include<event2/buffer.h>
#include<event2/util.h>

class CTcpClientImpl : public CTcpClient
{
public:
    CTcpClientImpl(ReadMsgCB readMsgCB, StatusCB statusCB=nullptr);
    virtual ~CTcpClientImpl();

    virtual bool Connect(const std::string &dstIp, const uint16_t &port, const int &reTimeval=0);
    virtual bool Run();

    virtual bool SetReadMsgCB(ReadMsgCB msgCB);
    virtual bool SetStatusCB(StatusCB statusCB);

    virtual bool SendMsg(const std::string &msg);

private:
    void OnReadMsg(bufferevent* bev);
    void OnStatus(bufferevent *bev, short event);
    friend void ReadMsg(bufferevent *bev, void *arg);
    friend void Status(bufferevent *bev, short event, void *arg);
    friend void CmdMsgCb(int fd, short evnts, void *arg);
    friend void ReconnectCB(int fd, short event, void *arg);

private:
    std::string _dstIp;
    uint16_t _dstPort;
    int _reconnectTimeval;
    event _reconnectEvent;

    ReadMsgCB _readMsgCB = nullptr;
    StatusCB _statusCB = nullptr;

    event_base *_pBase = nullptr;
    bufferevent *_pBev = nullptr;

    event *_pCmdEvent = nullptr;
};

#endif // _TCP_CLIENT_IMPL_H_